package mk.com.ldm.corepoint.implementation.server;

import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import mk.com.ldm.corepoint.implementation.shared.TableColumn;
import mk.com.ldm.corepoint.implementation.shared.TableData;
import mk.com.ldm.corepoint.implementation.shared.TableRow;
import mk.com.ldm.corepoint.implementation.shared.TableRows;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

public class ReportGenerator {

	private static ReportGenerator reportGenerator;

	private String FILE = "";
	private static Font catFont = new Font(Font.FontFamily.HELVETICA, 18,
			Font.BOLD);
	private static Font redFont = new Font(Font.FontFamily.HELVETICA, 12,
			Font.NORMAL, BaseColor.RED);
	private static Font subFont = new Font(Font.FontFamily.HELVETICA, 16,
			Font.BOLD);
	private static Font smallBold = new Font(Font.FontFamily.HELVETICA, 12,
			Font.BOLD);
	private static Font normalFont = new Font(Font.FontFamily.HELVETICA, 8,
			Font.NORMAL);
	private static Font boldFont = new Font(Font.FontFamily.HELVETICA, 8,
			Font.BOLD);
	private static Font italicFont = new Font(Font.FontFamily.HELVETICA, 8,
			Font.ITALIC);

	public static ReportGenerator getInstance() {
		if (reportGenerator == null)
			reportGenerator = new ReportGenerator();
		return reportGenerator;
	}

	protected ReportGenerator() {

	}

	/**
	 * TODO: Input query string, execute, generate file
	 */
	public String generateReport(String objectName, TableRows tableRows,
			HashMap<String, Boolean> visible, int pageType) {

		String DATE_FORMAT = "dd-MM-yyyy_HH.mm.ss";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);

		FILE = "../war/reports/" + objectName + "_" + sdf.format(new Date())
				+ ".pdf";
		Document document;
		try {
			if (pageType == 0)
				document = new Document(PageSize.A4);
			else
				document = new Document(PageSize.A4.rotate());
			PdfWriter.getInstance(document, new FileOutputStream(FILE));
			document.open();
			addMetaData(document);
			addTitlePage(document, objectName);
			createTable(document, tableRows, visible);
			document.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return objectName + "_" + sdf.format(new Date()) + ".pdf";

	}

	private static void addMetaData(Document document) {
		document.addTitle("Report");
		document.addSubject(" ");
		document.addKeywords(" ");
		document.addAuthor("LDM Ideas");
		document.addCreator("LDM Ideas");
	}

	private static void addTitlePage(Document document, String title)
			throws DocumentException {
		Paragraph preface = new Paragraph();
		addEmptyLine(preface, 1);
		preface.add(new Paragraph(title + " report", catFont));
		addEmptyLine(preface, 1);
		preface.add(new Paragraph("Generated on: " + new Date(), smallBold));
		addEmptyLine(preface, 3);
		document.add(preface);
		document.add(new Paragraph());
	}

	private static void createTable(Document document, TableRows tableRows,
			HashMap<String, Boolean> visible) throws BadElementException {

		int visibleColumns = 0;
		Set<String> keys = visible.keySet();
		Iterator<String> iterator = keys.iterator();
		while (iterator.hasNext()) {
			if (visible.get(iterator.next())) {
				visibleColumns++;
			}
		}

		PdfPTable table = new PdfPTable(visibleColumns);
		table.setWidthPercentage((float) 98);

		for (TableColumn col : tableRows.getColumns()) {
			if (visible.get(col.getHeader())) {
				PdfPCell c = new PdfPCell(new Phrase(col.getHeader(), boldFont));
				c.setHorizontalAlignment(Element.ALIGN_CENTER);
				table.addCell(c);
			}
		}
		table.setHeaderRows(1);

		int i = 0;
		for (TableRow row : tableRows.getRows()) {
			i = 0;
			for (TableData data : row.getTableData()) {
				if (visible.get(tableRows.getColumns().get(i).getHeader())) {
					PdfPCell c = new PdfPCell(new Phrase(data.getValue(),
							normalFont));
					c.setHorizontalAlignment(Element.ALIGN_CENTER);
					c.setVerticalAlignment(Element.ALIGN_MIDDLE);
					table.addCell(c);
				}
				i++;
			}
		}
		try {
			document.add(table);
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private static void addEmptyLine(Paragraph paragraph, int number) {
		for (int i = 0; i < number; i++) {
			paragraph.add(new Paragraph(" "));
		}
	}

}
